#include "transport.h"

#include "drivers/drivers.h"


namespace evm { namespace messaging {

Transport::Transport(ConfigOptsPtr conf, DriverPtr driver)
: conf(conf), driver(driver) {
    driver->start();
}

Transport::~Transport() {
    driver->stop();
}

Json Transport::send(TargetPtr target, Json &&msg, bool wait_for_reply, int timeout, int retry) {
    return driver->send(target, std::move(msg), wait_for_reply, timeout, retry);
}

void Transport::send_notification(TargetPtr target, Json &&msg, int retry) {
    return driver->send_notification(target, std::move(msg), retry);
}

ListenerPtr Transport::listen(TargetPtr target) {
    return driver->listen(target);
}

ListenerPtr Transport::listen_for_notifications(const vector<TargetPriority> &targets_and_priorities) {
    return driver->listen_for_notifications(targets_and_priorities);
}

TransportPtr get_transport(ConfigOptsPtr conf) {
    string rpc_backend = (*conf)["rpc_backend"];
    if (rpc_backend == "redis") {
        string redis_address = (*conf)["rpc_redis_address"];

        /* TODO: need more strict check for ip and port. */
        auto addr_pair = str::split(redis_address, ":");
        string ip = addr_pair[0];
        int port = addr_pair.size() > 1 ? std::stoi(addr_pair[1]) : 6379;
        auto driver = DriverPtr(new RedisDriver(ip, port));
        return make_shared<Transport>(conf, driver);
    }
    /* Other rpc backends ... */

    throw invalid_argument("Rpc backend '" + rpc_backend + "' not found.");
}

}}
